package builders

import (
	"bytes"
	"context"
	"fmt"
	configv1 "github.com/shenyisyn/dbcore/pkg/apis/dbconfig/v1"
	v1 "k8s.io/api/apps/v1"
	v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/apimachinery/pkg/util/yaml"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"text/template"
)

type DeployBuilder struct {
	deploy *v1.Deployment
	config *configv1.DbConfig
	client.Client
}

func deployName(name string) string {

	return "dbcore-" + name
}

//构建 deploy 创建器
func NewDeployBuilder(config *configv1.DbConfig, c client.Client) (*DeployBuilder, error) {

	deploy := &v1.Deployment{}
	err := c.Get(context.Background(), types.NamespacedName{
		Name: deployName(config.Name), Namespace:config.Namespace,
	}, deploy)
	if err != nil {
		deploy.Name, deploy.Namespace =config.Name,config.Namespace
		tpl, err := template.New("deploy").Parse(deptpl)
		var tplRet bytes.Buffer
		if err != nil {
			return nil, err
		}
		err = tpl.Execute(&tplRet, deploy)
		if err != nil {
			return nil, err
		}

		err = yaml.Unmarshal(tplRet.Bytes(), deploy)
		if err != nil {
			return nil, err
		}
	}
	return &DeployBuilder{deploy: deploy, Client: c,config: config}, nil
}

//设置 副本
func (this *DeployBuilder) Replicas(r int) *DeployBuilder {
	*this.deploy.Spec.Replicas = int32(r)
	return this
}

func (this *DeployBuilder)apply() *DeployBuilder  {

	*this.deploy.Spec.Replicas = int32(this.config.Spec.Replicas)
	return this
}

func (this *DeployBuilder)SetOwner() *DeployBuilder {
	this.deploy.OwnerReferences = append(this.deploy.OwnerReferences,v12.OwnerReference{
		APIVersion: this.config.APIVersion,
		Kind: this.config.Kind,
		Name: this.config.Name,
		UID: this.config.UID,
	})
	return this
}


//构建出  deployment
func (this *DeployBuilder) Build(ctx context.Context) error {
	if this.deploy.CreationTimestamp.IsZero() {
		this.apply().SetOwner()
		return this.Create(ctx, this.deploy)
	}else {
		patch := client.MergeFrom(this.deploy.DeepCopy())
		this.apply()
		this.Patch(ctx,this.deploy,patch)
	}



	this.config.Status.Ready=fmt.Sprintf("%d/%d",this.deploy.Status.ReadyReplicas,this.config.Spec.Replicas)
	this.config.Status.Replicas=this.deploy.Status.ReadyReplicas

	err:=this.Client.Status().Update(ctx,this.config)
	err=this.Client.Status().Update(ctx,this.config)
	if err!=nil{
		return err
	}
	//	return this.deploy
	return nil
}
